<template>
  <div>
    <n-space style="margin-bottom: 10px" justify="space-between">
      <n-space>
        <n-select
            style="width: 150px"
            :options="videoCutPicType"
            v-model:value="extractOption">
        </n-select>
        <n-button type="success" @click="deduplicationModalShow=true">抽帧分析</n-button>
        <n-button type="info" @click="batchScreenshotSetting">批量去水印</n-button>
        <n-button type="primary" @click="reWriteTableShow=true">文本改写</n-button>
        <n-button type="warning" @click="getText">查看文本</n-button>
      </n-space>

      <n-space>
        <n-tag type="primary" size="large">分镜总数:{{ tableTotal }},当前显示:{{ videoTextList.length }}</n-tag>
        <n-button type="primary"
                  @click="paginationReactive.page=1;paginationReactive.pageSize=1000;videoTextList=[];getVideoText()">
          加载全部
        </n-button>
      </n-space>
    </n-space>
    <n-grid x-gap="5">
      <n-gi :span="16">
        <n-spin :show="tableLoading" size="large">
          <div class="table-container"
               :style="{ height: `${clientHeight - 165}px`, overflowY:`scroll`, scrollbarWidth:`auto`}"
               @scroll="loadMore" ref="scrollbarRef">
            <n-table striped :single-line="false">
              <n-thead>
                <n-tr>
                  <n-th></n-th>
                  <n-th>#</n-th>
                  <n-th>操作</n-th>
                  <n-th>时间轴(秒)</n-th>
                  <n-th>文本内容</n-th>
                  <n-th>参考图</n-th>
                </n-tr>
              </n-thead>
              <n-tbody>
                <n-tr v-for="item in videoTextList" :key="item.id" @click="selectItem(item)">
                  <n-td style="width: 25px">
                    <n-checkbox v-model:checked="item.checked"></n-checkbox>
                  </n-td>
                  <n-td style="width: 50px">{{ item.orderNum }}</n-td>
                  <n-td>
                    <n-button type="warning" style="width: 80px;" @click="deleteBoard(item)" block>删除</n-button>
                    <n-button type="primary" style="width:80px;margin-top: 5px;" @click="addBoard(item)" block>拆分</n-button>
                    <n-button type="success" style="width:80px;margin-top: 5px;" @click="singleScreenshotSetting(item)" block>去水印</n-button>
                  </n-td>
                  <n-td style="width: 80px">
                    <n-space>
                      <n-tag type="success">
                        <div style="width: 80px;text-align: center;">
                          {{ parseFloat(item.startTime).toFixed(2) }}
                        </div>
                      </n-tag>
                    </n-space>
                    <n-space style="margin-top: 2px;">
                      <n-tag style="width: 100%" type="warning">
                        <div style="width: 80px;text-align: center;">
                          {{ parseFloat(item.endTime).toFixed(2) }}
                        </div>
                      </n-tag>
                    </n-space>
                  </n-td>
                  <n-td>
                    <VueDraggableNext v-model="item.sentenceList" handle=".handle" group="storySentence"
                                      @add="onStorySentenceAdd" @change="onStorySentenceChange">
                      <n-input-group v-if="options" v-for="(sentence,i) in item.sentenceList" style="margin-top: 5px;">
                        <n-popselect
                            v-if="voiceConfig && voiceConfig.planType==='systemVoice'"
                            @update:value="updateAudioConfig($event,sentence)"
                            v-model:value="sentence.audioConfig.voiceName"
                            :options="options"
                            scrollable
                            trigger="click">
                          <n-button class="handle" type="primary">
                            {{ getVoiceLabelName(sentence.audioConfig) }}
                          </n-button>
                        </n-popselect>
                        <n-button
                            v-if="voiceConfig &&( voiceConfig.planType == 'videoVoice' || voiceConfig.planType == 'uploadVoice')"
                            scrollable
                            type="primary"
                            trigger="click"
                            class="handle">
                          拖拽
                        </n-button>
                        <n-tooltip trigger="hover">
                          <template #trigger>
                            <n-button type="info" @click="sentenceMerge(sentence,'up')">
                              <n-icon>
                                <ArrowUp/>
                              </n-icon>
                            </n-button>
                          </template>
                          向上合并
                        </n-tooltip>
                        <n-input
                            v-model:value="item.sentenceList[i].content"
                            style="width: 400px;"
                            @keydown.enter="handlerEnter(item.sentenceList[i], $event)"
                            @update:value=" item.sentenceList[i].isChange = 1"
                            @blur="updateSentence(item.sentenceList[i])">
                        </n-input>
                        <n-tooltip trigger="hover">
                          <template #trigger>
                            <n-button type="info" @click="sentenceMerge(sentence,'down')">
                              <n-icon>
                                <ArrowDown/>
                              </n-icon>
                            </n-button>
                          </template>
                          往下合并
                        </n-tooltip>
                        <n-popconfirm @positive-click="deleteSentence(sentence)">
                          <template #trigger>
                            <n-button type="warning">
                              <n-icon>
                                <CloseSharp/>
                              </n-icon>
                            </n-button>
                          </template>
                          确定删除该句内容吗？
                        </n-popconfirm>
                      </n-input-group>
                    </VueDraggableNext>
                  </n-td>
                  <n-td style="width: 120px;">
                    <n-image
                        v-if="item.examplePic"
                        height="100"
                        :lazy="true"
                        :src="fileFunction.getViewFilePathByUserFileId(item.examplePic)"></n-image>
                  </n-td>
                </n-tr>
              </n-tbody>
            </n-table>
          </div>
          <template #description>
            正在努力加载...请耐心等待
          </template>
        </n-spin>
      </n-gi>
      <n-gi :span="8">
        <n-card title="图片选择">
          <template #header-extra>
            <n-button type="primary" @click="randomScreentshot" :loading="randomScreentshotLoading">随机截图5张
            </n-button>
          </template>
          <!--          :style="{ height: `${clientHeight - 165}px` }-->
          <n-scrollbar :style="{maxHeight:`${clientHeight - 260}px`}">
            <n-grid x-gap="2" :cols="2">
              <n-gi v-for="imageFile in filterScreenshotList">
                <n-card>
                  <template #cover>
                    <n-image
                        :width="300"
                        @click="clickImg(storyPaintLog)"
                        style="margin-left: 10px;"
                        :src=fileFunction.getViewFilePathByUserFileId(imageFile.userFileId)
                    />
                  </template>
                  <template #footer>
                    <n-checkbox @update:checked="examplePicSelect(imageFile)" v-model:checked="imageFile.checked">
                      {{ imageFile.fileName }}
                    </n-checkbox>
                  </template>
                </n-card>
              </n-gi>
            </n-grid>
          </n-scrollbar>

        </n-card>
      </n-gi>
    </n-grid>
    <n-modal
        v-model:show="progressModal"
        class="custom-card"
        style="width: 500px"
        preset="card"
        :mask-closable="false"
        title="图片去重任务进度"
        size="huge"
        :bordered="false"
    >
      <n-h4>一共有{{ totalNum }}图片去重</n-h4>
      <n-space justify="space-around">
        <n-statistic label="当前进度:" :value="finishNum">
          <template #prefix>
          </template>
          <template #suffix>
            / {{ totalNum }}
          </template>
        </n-statistic>
      </n-space>
      <n-progress
          type="line"
          :percentage=" finishNum === 0? 0 : Math.round(finishNum/totalNum *100) "
          :height="30"
          :border-radius="5"
          :fill-border-radius="0"
      />
    </n-modal>


    <n-modal
        v-model:show="deduplicationModalShow"
        class="custom-card"
        style="width: 500px"
        preset="card"
        :mask-closable="false"
        title="图片抽帧去重"
        size="huge"
        :bordered="false"
    >
      <n-form-item label="相似度阈值">
        <n-input-number
            v-model:value="similarity"
            :min="50"
            :max="99"
            :show-button="false"
            style="width: 100%"
        >
          <template #suffix>
            %
          </template>
        </n-input-number>
      </n-form-item>
      <template #footer>
        <n-button type="primary" @click="videoScreenshotAndStartImageDeduplicationTask"
                  :loading="imageDeduplicationLoading" block>去重并合并分镜
        </n-button>
      </template>
    </n-modal>


    <n-modal
        v-model:show="addModalShow"
        style="width: 600px"
        preset="card"
        title="新增分镜"
        size="huge"
        :bordered="false"
    >
      <n-form>
        <n-h4>您当前在第
          <n-tag type="primary">{{ addNum }}</n-tag>
          分镜插入分镜,新增分镜编号为:
          <n-tag type="primary">{{ addNum + 1 }}</n-tag>
        </n-h4>
        <n-form-item label="文本内容">
          <n-input type="textarea" style="height: 100px;" v-model:value="editDataForm.content"></n-input>
        </n-form-item>
        <n-row>
          <n-col :span="12">
            <n-form-item label="开始时间">
              <n-input-number
                  v-model:value="editDataForm.startTime"
                  :min="editDataForm.lastStartTime + 0.1"
                  :max="editDataForm.endTime - 0.1" :step="0.1">
              </n-input-number>
            </n-form-item>
          </n-col>
          <n-col :span="12">
            <n-form-item label="结束时间">
              <n-input-number v-model:value="editDataForm.endTime" readonly></n-input-number>
            </n-form-item>
          </n-col>
        </n-row>
      </n-form>
      <template #footer>
        <n-space justify="end">
          <n-button @click="addModalShow=false">取消</n-button>
          <n-button type="primary" @click="addOrUpdateBoard">确认</n-button>
        </n-space>
      </template>
    </n-modal>

    <n-modal
        v-model:show="removeMarkModalShow"
        class="custom-card"
        preset="card"
        :style="{
          width: '900px'
        }"
        title="选择水印区域"
        size="huge"
        :bordered="false"
    >
      <RemoveWaterMarker
          :screenshotList="removeWaterMarkerData.screenshotList.splice(0,5)"
          :story="removeWaterMarkerData.story"
          :mode="removeWaterMarkerData.mode"
          :storyBoardId="removeWaterMarkerData.storyBoardId"
          @loadSuccess-Event="loadSuccessEvent"
      >
      </RemoveWaterMarker>
    </n-modal>

    <n-modal v-model:show="txtShow">

      <n-card
          style="width: 600px"
          title="文本查看"
          :bordered="false"
          size="huge"
          role="dialog"
          aria-modal="true"
      >
        <n-row>
          <n-col span="24">
            <n-form-item :show-label="false" :label="`原文   共: `+ ( (sentences.match(/\n/g) || []).length + 1) +`行`">
              <n-input
                  type="textarea"
                  readonly
                  style="height: 500px"
                  v-model:value="sentences">
              </n-input>
            </n-form-item>


          </n-col>
<!--          <n-col span="12" style="padding-left: 5px;">-->
<!--            <n-form-item :label="`改文   共: `+( (newSentences.match(/\n/g) || []).length  + 1 )+`行`">-->
<!--              <n-input-->
<!--                  type="textarea"-->
<!--                  style="height: 300px"-->
<!--                  v-model:value="newSentences">-->
<!--              </n-input>-->
<!--            </n-form-item>-->
<!--          </n-col>-->
        </n-row>
<!--        <n-h3>修改内容</n-h3>-->
<!--        <Diff-->
<!--            mode="split"-->
<!--            theme="dark"-->
<!--            language="plaintext"-->
<!--            :prev="sentences"-->
<!--            :current="newSentences"-->
<!--            :folding="true"-->
<!--            :input-delay="0"-->
<!--            :virtual-scroll="{ height: 300, lineMinHeight: 24, delay: 100 }"-->
<!--        />-->

      </n-card>
    </n-modal>

    <n-drawer v-model:show="reWriteTableShow" :width="drawerWidth" :close-on-esc="false" :mask-closable="false">
      <n-drawer-content title="文案改写" closable>
        <VideoRewrite :storyId="props.story.id" :closeAction="rewriteWindowClose"></VideoRewrite>
      </n-drawer-content>
    </n-drawer>

  </div>
</template>
<script setup lang="ts">
import {NButton, NImage, NInput, NSelect, NTag, useMessage} from 'naive-ui'
import {nextTick, onMounted, reactive, ref} from "vue"
import {storyController} from "@/api/story/story.api"
import {storyBoardController} from "@/api/controller/story/storyBoard.api"
import {storeToRefs} from "pinia"
import {useSystemStore} from "@/store/modules/useSystemStore"
import {creatorDict} from '@/dictionary/creatorDict'
import fileFunction from "@/libs/globalFunction/file"
import {videoController} from "@/api/controller/video/videoController.api"
import RemoveWaterMarker from "@/components/removewatermarker/index.vue"
import {VueDraggableNext} from 'vue-draggable-next'
import {ArrowUp, ArrowDown, CloseSharp} from '@vicons/ionicons5'
import {storySentenceController} from "@/api/controller/story/storySentenceController.api"
import {v4 as uuidv4} from "uuid"
import VideoRewrite from "@/components/gpt/rewrite/videoStoryRewrite.vue"
import {Diff} from "vue-diff";
import Bus from "@/components/file/box/GlobalUploader/utils/bus";

const drawerWidth = ref(0)
const message = useMessage()
const story = ref("")
const progressModal = ref(false)
const extractOption = ref("1")
const tableLoading = ref(false)
const {videoCutPicType} = creatorDict()
const videoTextList = ref([])
const checkedRowKeys = ref([0])
const screenshotList = ref([])
const filterScreenshotList = ref([])
const picMap = reactive(new Map([])) as any
const totalNum = ref(0)
const finishNum = ref(0)
const deduplicationModalShow = ref(false)
const scrollbarRef = ref(false)
const txtShow = ref(false)
const {
  clientHeight,
  layoutHeaderHeight,
  darkTheme,
  tabsHeight
} = storeToRefs(useSystemStore());

const similarity = ref(98)
const imageDeduplicationLoading = ref(false)
const removeMarkModalShow = ref(false)
const voiceList = ref()
const options = ref([]) as any
const voiceConfig = ref(null)
const reWriteTableShow = ref(false)
const sentences = ref('')
const newSentences = ref('')
// 使用 ref 创建防抖计时器
const debounceTimer = ref(null) as any


const getVoiceList = async () => {
  await storyController.listVoiceActors(props.story.id).then(res => {
    if (res.code === 200) {
      voiceList.value = res.data
      voiceList.value.forEach((item: any) => {
        options.value.push({
          label: item.localName + "|" + item.localeNameZh + "|" + item.age,
          value: item.shortName,
          localName: item.localName
        })
      })
    } else {
      message.error(res.msg)
    }
  })
}

const editDataForm = reactive({
  id: "",
  chapterId: "",
  content: "",
  prompt: "",
  promptEn: "",
  orderNum: -1,
  characterName: "",
  startTime: null,
  lastStartTime: 0,
  endTime: 0,
  examplePic: ""
})

const addNum = ref(0)
const addModalShow = ref(false)
const addOrUpdateLoading = ref(false)
const randomScreentshotLoading = ref(false)
const storyCreatorConfig =  ref({
    paintType: '',
    resourceId: '',
    chapterId: '',
    voiceType: '',
    paintConfigText:'',
    voiceConfigText:''
})
const props = defineProps({
  story: {
    type: Object,
    required: true
  }
})


const removeWaterMarkerData = {
  mode: 'video',
  story: props.story,
  storyBoardId: '',
  screenshotList: []
}

onMounted(async () => {
  await getStoryPaintConfig()
  await getVoiceList()
  await appendVideoText()
  drawerWidth.value = window.innerWidth * 0.8
  window.addEventListener('resize', handleResize)
})

const handleResize = () => {
  drawerWidth.value = window.innerWidth * 0.8
}

const loadMore = (e: any) => {
  clearTimeout(debounceTimer.value);
  debounceTimer.value = setTimeout(() => {
    const scrollWrapperRef = scrollbarRef.value
    const {scrollTop, scrollHeight, clientHeight} = scrollWrapperRef
    if (scrollTop + clientHeight >= scrollHeight - 300) {
      if (videoTextList.value.length == tableTotal.value) {
        return
      }
      paginationReactive.page = paginationReactive.page + 1
      appendVideoText()
    }
  }, 200);
}

const tableTotal = ref(0)
const paginationReactive = reactive({
  page: 1,
  pageSize: 20,
  pageSizes: [20]
})

const onPageSizeChange = (pageSize: number) => {
  paginationReactive.pageSize = pageSize
  getVideoText()
}

const onPageChange = (page: number) => {
  paginationReactive.page = page
  getVideoText()
}



const appendVideoText = async () => {
  tableLoading.value = true
  await storyController.getVideoText({
    storyId: props.story.id,
    page: paginationReactive.page,
    pageSize: paginationReactive.pageSize
  }).then(res => {
    if (res.code === 200) {
      if (videoTextList.value == null || videoTextList.value.length == 0) {
        videoTextList.value = res.data.records
      } else {
        res.data?.records.forEach((item: any) => {
          videoTextList.value.push(item)
        })
      }
      // videoTextList.value = res.data.records
      tableTotal.value = res.data.total

    }
  }).finally(() => {
    tableLoading.value = false
  })
  await getScreenshot()
}

const getVideoText = async () => {
  tableLoading.value = true
  await storyController.getVideoText({
    storyId: props.story.id,
    page:  1 ,
    pageSize: paginationReactive.pageSize * paginationReactive.page
  }).then(res => {
    if (res.code === 200) {
      videoTextList.value = res.data.records
      // if (videoTextList.value == null || videoTextList.value.length == 0) {
      //   videoTextList.value = res.data.records
      // } else {
      //   res.data?.records.forEach((item: any) => {
      //     videoTextList.value.push(item)
      //   })
      // }
      // videoTextList.value = res.data.records
      tableTotal.value = res.data.total

    }
  }).finally(() => {
    tableLoading.value = false
  })
  await getScreenshot()
}

const videoScreenshotAndStartImageDeduplicationTask = () => {
  if (videoTextList.value.length > 0) {
    totalNum.value = 0
    finishNum.value = 0
    const param = {
      storyId: props.story.id,
      screenshotType: extractOption.value,
      userFileId: props.story.userFileId,
      similarityThreshold: similarity.value / 100
    }
    // imageDeduplicationLoading.value = true
    imageDeduplicationLoading.value = true
    // progressModal.value = true
    videoController.videoScreenshotAndStartImageDeduplicationTask(param, 20 * 60 * 1000,
        imageDeduplicationLoading, progressModal, totalNum, finishNum).then(res => {
      deduplicationModalShow.value = false
      progressModal.value = false
      window.$message.success("图片抽帧成功！")
      paginationReactive.page = 1
      paginationReactive.pageSize = 20
      // videoTextList.value = []
      getVideoText()
    }).finally(() => {
      imageDeduplicationLoading.value = false
    })
  }
}

const randomScreentshot = () => {
  const row = videoTextList.value[checkedRowKeys.value[0]]
  const exceptNumber = []
  picMap.get(checkedRowKeys.value[0]).forEach((item: any) => {
    exceptNumber.push(parseFloat(item.fileName))
  })
  const param = {
    startTime: row.startTime,
    endTime: row.endTime,
    userFileId: props.story.userFileId,
    screenshotNumber: 5,
    exceptNumber: exceptNumber,
    storyId: props.story.id
  }
  randomScreentshotLoading.value = true
  videoController.randomScreenshot(param).then(res => {
    if (res.code === 200) {
      getScreenshot()
    }
  }).finally(() => {
    randomScreentshotLoading.value = false
  })
}

/**
 * 获取截图
 */
const getScreenshot = async () => {
  const param = {
    storyId: props.story.id,
    userFileId: props.story.userFileId
  }
  videoController.getScreenshotList(param).then(res => {
    if (res.code === 200) {
      screenshotList.value = res.data
      // 排序
      screenshotList.value.sort((a: any, b: any) => {
        return parseFloat(a.fileName) - parseFloat(b.fileName)
      })
      groupPic()
    } else {
      message.error(res.msg)
    }
  })
}


const updateBoard = (row: any) => {
  storyBoardController.addOrUpdateBoard(row).then(res => {
    if (res.code !== 200) {
      message.error(res.msg)
    }
  })
}


// 分组pic
const groupPic = () => {
  videoTextList.value.forEach((item: any, index: number) => {
    item.index = index
    let timeZonePic = getTimeZonePic(item.startTime, item.endTime)
    let hasChecked = false
    timeZonePic.forEach(pic => {
      if (item.examplePic) {
        if (item.examplePic == pic.userFileId) {
          pic.checked = true
          hasChecked = true
        } else {
          pic.checked = false
        }
      }
    })
    picMap.set(index, timeZonePic)
  })

  if (checkedRowKeys.value != null && checkedRowKeys.value.length > 0) {
    filterScreenshotList.value = picMap.get(checkedRowKeys.value[0])
  } else {
    filterScreenshotList.value = picMap.get(0)
  }
}


const getTimeZonePic = (startTime: number, endTime: number) => {
  return screenshotList.value.filter((item: any) => {
    return item.fileName > startTime && item.fileName <= endTime
  })
}

const examplePicSelect = (imageFile: any) => {
  nextTick(() => {
    const picList = picMap.get(checkedRowKeys.value[0])
    if (imageFile.checked) {
      picList.forEach(pic => {
        pic.checked = false
      })
      imageFile.checked = true
      videoTextList.value[checkedRowKeys.value[0]].examplePic = imageFile.userFileId
    }
    // 更新updateBoard
    updateBoard(videoTextList.value[checkedRowKeys.value[0]])
  })
}


const addBoard = (row: any) => {
  Object.keys(editDataForm).forEach(key => {
    editDataForm[key] = ''
  })
  addNum.value = row.orderNum
  editDataForm.orderNum = row.orderNum + 1
  editDataForm.chapterId = props.story.id
  editDataForm.lastStartTime = row.startTime
  editDataForm.endTime = row.endTime
  addModalShow.value = true
}


const getVoiceLabelName = (voiceConfig: any) => {
  const selectItems = options.value.filter((item: any) => {
    return item.value == voiceConfig.voiceName
  });
  if (selectItems.length > 0) {
    return selectItems[0].localName
  } else {
    voiceConfig.voiceName = options.value[0].value
    return options.value[0].localName
  }
}

const addOrUpdateBoard = () => {
  const lastBoard = videoTextList.value[addNum.value]
  lastBoard.endTime = editDataForm.startTime
  let timeZonePic = getTimeZonePic(editDataForm.startTime, editDataForm.endTime)
  if (timeZonePic.length == 1) {
    editDataForm.examplePic = timeZonePic[0].userFileId
  } else if (timeZonePic.length > 1) {
    editDataForm.examplePic = timeZonePic[1].userFileId
  }
  const param = [editDataForm, lastBoard]
  console.log(param)
  addOrUpdateLoading.value = true
  storyBoardController.addOrUpdateBoards(param).then(res => {
    addOrUpdateLoading.value = false
    if (res.code === 200) {
      message.success(res.msg)
      addModalShow.value = false
      getVideoText()
    } else {
      message.error(res.msg)
    }
  }).finally(() => {
    addOrUpdateLoading.value = false
  })
}

/**
 * 删除分镜
 * @param row
 */
const deleteBoard = (row: any) => {
  const dialog = window.$dialog.warning({
    title: "温馨提醒",
    content: "是否继续删除第(" + row.orderNum + ")号分镜信息？",
    positiveText: "确定",
    negativeText: "取消",
    onPositiveClick: () => {
      dialog.loading = true
      return new Promise((resolve, reject) => {
        storyBoardController.deleteBoard(row.id, row.chapterId).then(res => {
          if (res.code === 200) {
            message.success(res.msg)
            resolve(true)
            paginationReactive.pageSize = videoTextList.value.length
            // videoTextList.value = []
            paginationReactive.page = 1
            getVideoText()
          } else {
            message.error(res.msg)
          }
        })
      })
    }
  })
}


const updateAudioConfig = (value: any, sentence: any) => {
  sentence.audioConfig.voiceName = value
  options.value.forEach((item: any) => {
    if (item.value === value) {
      sentence.audioConfig.voiceLocaleName = item.localeName
    }
  })
  updateStorySentence(sentence)
}

const updateStorySentence = (storySentence: any) => {
  storySentenceController.addOrUpdateStorySentence(storySentence).then(res => {
    if (res.code != 200) {
      message.error(res.msg)
    }
  })
}


/***
 * 按下回车键,分镜内新增句子
 * @param item
 * @param event
 */
const handlerEnter = (item: any, event: any) => {
  const cursorPosition = event.target.selectionStart;
  const inputBeforeCursor = item.content.substring(0, cursorPosition);
  const inputAfterCursor = item.content.substring(cursorPosition);
  const sentences = findSentences(item.storyBoardId)
  const addSentences = {...item}
  addSentences.orderNum = addSentences.orderNum + 1
  addSentences.content = inputAfterCursor
  addSentences.id = uuidv4()
  for (let i = 0; i < sentences.length; i++) {
    const sentence = sentences[i];
    if (sentence.orderNum < item.orderNum) {
      continue
    }
    if (sentence.orderNum == item.orderNum) {
      sentences[i].content = inputBeforeCursor
    } else {
      sentence.orderNum = sentence.orderNum + 1
    }
  }
  sentences.push(addSentences)
  sentences.sort((a: any, b: any) => {
    return a.orderNum - b.orderNum
  })
  let storyBoardIdList = [item.storyBoardId]
  updateSentences(storyBoardIdList, sentences)
}


const sentenceMerge = (sentence: any, type: string) => {
  const orderNum = sentence.orderNum
  const sentences = findSentences(sentence.storyBoardId)
  if (orderNum == 0 && type == 'up') {
    // 找到上一个分镜
    const storyBoard = findStoryBoard(sentence.storyBoardId)
    if (storyBoard.orderNum == 0) {
      message.error('无法向上合并了')
      return
    }
    let updateSentenceCollection = []
    const lastStoryBoard = videoTextList.value[storyBoard.orderNum - 1]
    const preSentences = lastStoryBoard.sentenceList
    // // // 找到合并的句子
    const preSentenceMerge = preSentences[preSentences.length - 1]
    preSentenceMerge.content = preSentenceMerge.content + sentence.content
    sentences.splice(orderNum, 1)
    sentences.forEach((item: any, index: number) => {
      item.orderNum = index
      updateSentenceCollection.push(item)
    })
    preSentences.forEach((item: any, index: number) => {
      item.orderNum = index
      updateSentenceCollection.push(item)
    })
    let storyBoardIdList = [lastStoryBoard.id, storyBoard.id]
    updateSentences(storyBoardIdList, updateSentenceCollection)
  } else if (orderNum == sentences.length - 1 && type == 'down') {
    const storyBoard = findStoryBoard(sentence.storyBoardId)
    if (storyBoard.orderNum == videoTextList.value.length - 1) {
      message.info('无法向下合并了')
      return
    }
    let updateSentenceCollection = []
    const nextStoryBoard = videoTextList.value[storyBoard.orderNum + 1]
    const nextSentences = nextStoryBoard.sentenceList
    // 找到合并的句子
    const nextSentenceMerge = nextSentences[0]
    nextSentenceMerge.content = sentence.content + nextSentenceMerge.content
    sentences.splice(orderNum, 1)
    sentences.forEach((item: any, index: number) => {
      item.orderNum = index
      updateSentenceCollection.push(item)
    })
    nextSentences.forEach((item: any, index: number) => {
      item.orderNum = index
      updateSentenceCollection.push(item)
    })
    let storyBoardIdList = [nextStoryBoard.id, storyBoard.id]
    updateSentences(storyBoardIdList, updateSentenceCollection)
  } else {
    // 分镜内合并
    if (type == 'up') {
      const preSentence = sentences[orderNum - 1]
      preSentence.content = preSentence.content + sentence.content
      sentences.splice(orderNum, 1)
    } else {
      const nextSentence = sentences[orderNum + 1]
      sentence.content = sentence.content + nextSentence.content
      sentences.splice(orderNum + 1, 1)
    }
    sentences.forEach((item: any, index: number) => {
      item.orderNum = index
    })
    let storyBoardIdList = [sentence.storyBoardId]
    updateSentences(storyBoardIdList, sentences)
  }
}


const updateSentences = (storyBoardIdList: any, sentenceList: any) => {
  const param = {
    sentences: sentenceList,
    storyBoardIdList: storyBoardIdList
  }
  storySentenceController.batchHandlerSentences(param).then(res => {
    if (res.code != 200) {
      message.error(res.msg)
    }
  })
}

const deleteSentence = (sentence: any) => {
  // 找到分镜
  const storySentence = findSentences(sentence.storyBoardId)
  storySentence.splice(sentence.orderNum, 1)
  storySentenceController.deleteStorySentence(sentence).then(res => {
    if (res.code != 200) {
      message.error(res.msg)
    }else {
      storySentence.forEach((item: any, index: number) => {
        item.orderNum = index
      })
      updateSentences([sentence.storyBoardId], storySentence)
    }
  })
}


/**
 * 分镜间移动
 */
const onStorySentenceAdd = () => {
  let storyBoardIdList = []
  let needToUpdateSentence = []
  let sentencesNeedToUpdate = findNeedToUpdateStoryBoard()
  console.log(sentencesNeedToUpdate)
  sentencesNeedToUpdate.forEach(uniqueSet => {
    uniqueSet.forEach(value => {
      storyBoardIdList.push(value)
      let sentences = findSentences(value)
      for (let i = 0; i < sentences.length; i++) {
        let sentence = sentences[i]
        sentence.storyBoardId = value
        sentence.orderNum = i
        needToUpdateSentence.push(sentence)
      }
    })
  })
  updateSentences(storyBoardIdList, needToUpdateSentence)
}

/**
 * 找出修改过的分镜
 */
const findNeedToUpdateStoryBoard = () => {
  return videoTextList.value.map(storyboard => {
    let uniqueSet = new Set(storyboard.sentenceList.map(item => item.storyBoardId));
    if (uniqueSet.size > 1) {
      return uniqueSet
    } else if (uniqueSet.size == 1 && storyboard.id != storyboard.sentenceList[0].storyBoardId) {
      uniqueSet.add(storyboard.id)
      return uniqueSet
    }
    return null; // 如果条件不满足，则返回null
  }).filter(result => result !== null);
}

const onStorySentenceChange = (event: any) => {
  if (event.moved) {
    /**
     * 分镜内移动
     */
    let storyBoardIdList = []
    const storyBoardId = event.moved.element.storyBoardId
    storyBoardIdList.push(storyBoardId)
    const sentences = findSentences(storyBoardId)
    sentences.forEach((item: any, index: number) => {
      item.orderNum = index
    })
    updateSentences(storyBoardIdList, sentences)
  }
}

/**
 * 根据分镜ID查询分镜的句子
 * @param storyBoardId
 */
const findSentences = (storyBoardId: string) => {
  for (let i = 0; i < videoTextList.value.length; i++) {
    if (videoTextList.value[i].id == storyBoardId) {
      return videoTextList.value[i].sentenceList
    }
  }
}

const findStoryBoard = (storyBoardId: string) => {
  for (let i = 0; i < videoTextList.value.length; i++) {
    if (videoTextList.value[i].id == storyBoardId) {
      return videoTextList.value[i]
    }
  }
}


const loadSuccessEvent = () => {
  removeMarkModalShow.value = false
  // paginationReactive.page = 1
  // paginationReactive.pageSize = 20
  // videoTextList.value = []
  getVideoText()
}

const selectItem = (item: any) => {
  videoTextList.value.forEach((item: any) => {
    item.checked = false
  })
  item.checked = !item.checked
  if (item.checked) {
    checkedRowKeys.value = [item.index]
  } else {
    checkedRowKeys.value = []
  }
  filterScreenshotList.value = picMap.get(item.index)
}

const nextStep = (callback: any) => {
  // 判断是否有空的分镜
  let hasEmpty = false
  videoTextList.value.forEach((item: any) => {
    if (item.sentenceList.length == 0) {
      hasEmpty = true
    }
  })
  if (hasEmpty) {
    message.error("不能有空的分镜,请删除空的分镜！")
    callback(false)
    return
  }

  storyController.checkVideoRepaintStoryBoard(props.story.id, "2").then(res => {
    if (res.code === 200) {
      callback(true)
    } else {
      message.error(res.data);
      callback(false)
    }
  })
}

const batchScreenshotSetting = () => {
  removeMarkModalShow.value = true
  removeWaterMarkerData.mode = 'batch'
  removeWaterMarkerData.screenshotList = screenshotList.value
  removeWaterMarkerData.story = props.story
}

const singleScreenshotSetting = (item: any) => {
  removeMarkModalShow.value = true
  removeWaterMarkerData.mode = 'single'
  removeWaterMarkerData.screenshotList = []
  removeWaterMarkerData.screenshotList.push({
    userFileId: item.examplePic
  })
  removeWaterMarkerData.storyBoardId = item.id
}

const getText = () => {
  storyController.getStorySentences(props.story.id).then(res => {
    if (res.code === 200) {
      txtShow.value = true
      sentences.value = ''
      newSentences.value = ''
      res.data.forEach((item: any) => {
        sentences.value += item.content + '\n'
        newSentences.value += item.content + '\n'
      })
    } else {
      message.error(res.msg)
    }
  })
}

const getStoryPaintConfig = async () =>{
    try{
        const res = await storyController.getStoryPaintConfig(props.story.id);
        if(res.code === 200){
            if(res.data != null) {
                // Object.assign(storyCreatorConfig, res.data)
                storyCreatorConfig.value = res.data
                voiceConfig.value = JSON.parse(res.data.voiceConfigText)
            }
        } else {
            window.$message.error(res.msg);
        }
    }catch (error){
        console.error(error);
    }
}

const rewriteWindowClose = async () => {
  reWriteTableShow.value = false
  paginationReactive.pageSize = videoTextList.value.length
  videoTextList.value = []
  paginationReactive.page = 1
  await appendVideoText()
}
const updateSentence = (item:any) =>{
  if(item.isChange == '1'){
    updateStorySentence(item)
  }
}
defineExpose({
  nextStep
})

Bus.on('refreshStoryConfig', async () => {
    await getStoryPaintConfig()
    await getVideoText()
})
</script>
